package cn.pconline.officialclub.service;

import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.officialclub.entity.OClubPv;
import cn.pconline.officialclub.entity.OClubVisitor;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gelivable.dao.Mid;
import org.gelivable.dao.SqlBuilder;

/**
 * 人气统计等相关
 *
 * @author <a href="mailto:chensy0203@163.com">chensy</a>
 */
public class OStatService extends ServiceKit {

    private static final HashMap<Integer, String> weekStr = new HashMap<Integer, String>();

    static {
        weekStr.put(1, "周日");
        weekStr.put(2, "周一");
        weekStr.put(3, "周二");
        weekStr.put(4, "周三");
        weekStr.put(5, "周四");
        weekStr.put(6, "周五");
        weekStr.put(7, "周六");
    }

    /**
     * 更新PV，每次+1
     *
     * @param oClubId
     * @param ymd
     * @return
     */
    public boolean createOrUpdatePv(long oClubId, int ymd) {
        Date now = new Date();
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("insert into ").appendSql(getTableName(OClubPv.class, oClubId)).appendSql(" ( o_club_id,ymd,pv,create_at,update_at ) values(")
                .appendValue(oClubId).appendSql(",")
                .appendValue(ymd).appendSql(",")
                .appendValue(1).appendSql(",")
                .appendValue(now).appendSql(",")
                .appendValue(now).appendSql(" ) on duplicate key update update_at = ").appendValue(now).appendSql(",pv=pv+1");
        return update(sql) > 0;
    }

    /**
     * 根据车友会获得总pv数
     *
     * @param oClubId
     * @return
     */
    public int countPvByClubId(long oClubId) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select sum(pv) from ").appendSql(getTableName(OClubPv.class, oClubId));
        sql.appendSql(" where o_club_id = ").appendValue(oClubId);
        return count(sql);
    }

    /**
     * 获取车友会某天的pv数
     *
     * @param oClubId
     * @return
     */
    public int countPvByClubId(long oClubId, int ymd) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select sum(pv) from ").appendSql(getTableName(OClubPv.class, oClubId));
        sql.appendSql(" where o_club_id = ").appendValue(oClubId).appendSql(" and ymd = ").appendValue(ymd);
        return count(sql);
    }

    /**
     * 转成JSON数组
     *
     * @param list
     * @return
     */
    public JSONArray toJSONArray(List<OClubPv> list) {
        JSONArray a = new JSONArray();
        for (OClubPv pv : list) {
            Calendar c = Calendar.getInstance();
            c.setTime(pv.getCreateAt());
            int k = c.get(Calendar.DAY_OF_WEEK);
            JSONObject o = new JSONObject();
            o.put("name", weekStr.get(k));
            o.put("value", pv.getPv());
            a.add(o);
        }
        return a;
    }

    /**
     * 根据车友会获取几天内的所有pv值 （查多少天，会返回多少天的对象）
     *
     * @param oClubI
     * @param day
     * @return
     */
    public List<OClubPv> getLatestClubPv(long oClubId, int day) {
        Date now = DateUtils.getNow();
        Date startDate = DateUtils.getSingleDateBefore(now, day);
        List<OClubPv> list = new ArrayList<OClubPv>(day);
        //算出要查询的数据日期范围
        int start = DateUtils.formatData2YMD(startDate);
        int end = DateUtils.formatData2YMD(now);
        List<OClubPv> pvs = getClubPvByDay(oClubId, start, end);
        //查询到的数据小于要查的天数,说明其中有没有数据的天数,需要补空
        if (pvs.size() < day) {
            //把查询到的数据转为map
            Map<Integer, OClubPv> pvMap = new HashMap<Integer, OClubPv>();
            if (pvs != null && !pvs.isEmpty()) {
                for (OClubPv clubPv : pvs) {
                    pvMap.put(clubPv.getYmd(), clubPv);
                }
            }
            for (int i = 0; i < day; i++) {
                //从第一天开始补起
                Date date = DateUtils.getDateAfter(startDate, i + 1);
                int current = DateUtils.formatData2YMD(date);
                //当天没数据补空
                OClubPv clubPv = pvMap.get(current);
                if (clubPv == null) {
                    clubPv = new OClubPv();
                    clubPv.setOClubId(oClubId);
                    clubPv.setYmd(DateUtils.formatData2YMD(date));
                    clubPv.setPv(0);
                    clubPv.setCreateAt(date);
                    clubPv.setUpdateAt(date);
                }
                list.add(clubPv);
            }
            return list;
        } else {
            return pvs;
        }
    }

    /**
     * 获取指定时间段内的PV量
     *
     * @param oClubId
     * @param startYmd
     * @param endYmd
     * @return
     */
    public List<OClubPv> getClubPvByDay(long oClubId, int startYmd, int endYmd) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select o_club_id,ymd from ").appendSql(getTableName(OClubPv.class, oClubId));
        sql.appendSql(" where o_club_id=").appendValue(oClubId).appendSql(" and ymd>").appendValue(startYmd).appendSql(" and ymd<=").appendValue(endYmd);
        return list(OClubPv.class, oClubId, sql);
    }

    /**
     * 创建访问记录
     *
     * @param clubVisitor
     * @return
     */
    public int addOrUpdateVisitor(long userId, long oClubId) {
        Date now = DateUtils.getNow();
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("insert into ").appendSql(getTableName(OClubVisitor.class)).appendSql(" ( o_club_id,user_id,visit_date,create_at ) values(");
        sql.appendValue(oClubId).appendSql(",").appendValue(userId).appendSql(",").appendValue(now).appendSql(",").appendValue(now);
        sql.appendSql(" ) on duplicate key update visit_date = ").appendValue(now);
        return update(sql);
    }

    /**
     * 获取前N个访客
     *
     * @param oClubId
     * @param num
     * @return
     */
    public List<User> getVisitorByClubId(long oClubId, int num) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select user_id from ").appendSql(getTableName(OClubVisitor.class));
        sql.appendSql(" where o_club_id = ").appendValue(oClubId).appendSql(" order by visit_date desc");
        return listLimit(User.class, sql, num);
    }
}
